<template>
  <view class="add-time-scene">
    <view class="settings-content">
      <view class="section-box">
        <view class="section-content">
          <view class="item-line">
            <view class="line-field">
              <view class="label">
                <text>时控名称</text>
              </view>
              <view class="operate">
                <input :disabled="!enableEdit" placeholder="请输入时控名称" v-model="form.name" maxlength="10" />
              </view>
            </view>
          </view>
          <view v-if="formVerify.nameError" class="error-tips">{{ formVerify.nameErrorTips }}</view>
        </view>
      </view>
      <view class="section-box">
        <view class="section-title"><view class="title">时控类型</view></view>
        <view class="section-content">
          <view class="item-line type-box">
            <view v-for="item in typeList" :key="item.value" class="radio-item" @click="form.type = item.value">
              <view class="like-radio" :class="{ active: form.type === item.value }"></view>
              <view class="label"> {{ item.name }} </view>
            </view>
          </view>
        </view>
      </view>
      <view v-if="form.type !== SCENE_TIME_TYPE.DAILY" class="section-box">
        <view class="section-title"><view class="title">日期</view></view>
        <view class="section-content">
          <view v-if="form.type === SCENE_TIME_TYPE.WEEKLY" class="item-line">
            <view class="week-box">
              <view
                v-for="item in weekdayList"
                :key="item.value"
                class="week-item"
                :class="{ active: form.weekdays.includes(item.value) }"
                @click="toggleWeekChecked(item.value)">
                {{ item.name }}
              </view>
            </view>
            <view v-if="formVerify.weekdayError" class="error-tips">{{ formVerify.weekdayErrorTips }}</view>
          </view>
          <view v-if="form.type === SCENE_TIME_TYPE.DATE_AREA" class="item-line">
            <uni-datetime-picker v-model="form.dateArea" type="daterange" />
            <view v-if="formVerify.dateAreaError" class="error-tips">{{ formVerify.dateAreaErrorTips }}</view>
          </view>
        </view>
      </view>
      <view class="section-box">
        <view class="section-title">
          <view class="title">时间段</view>
          <view class="add-time" @click="addSceneTime">
            <text class="iconfont icon-add"/>
            新增
          </view>
        </view>
        <view class="section-content">
          <view class="item-line">
            <view v-for="item in form.timeList" :key="item.key" class="time-item">
              <view v-if="form.timeList.length > 1" class="delete-item" @click="removeSceneTime(item)">
                <text class="iconfont icon-close-fill"/>
              </view>
              <view class="time-box">
                <picker
                    mode="time"
                    :value="item.startTime"
                    @change="changeTime($event, item, 'start')">
                  <view class="picker-box">
                    <view v-if="item.startTime" class="start time-picker">
                      {{ item.startTime }}
                    </view>
                    <view v-else class="start placeholder">
                      请选择开始时间
                    </view>
                    <view class="iconfont icon-arrow-down"/>
                  </view>
                </picker>
                <picker
                    mode="time"
                    :value="item.endTime"
                    :start="item.startTime"
                    @change="changeTime($event, item, 'end')">
                  <view class="picker-box">
                    <view v-if="item.endTime" class="end time-picker">
                      {{ item.endTime }}
                    </view>
                    <view v-else class="end placeholder">
                      请选择结束时间
                    </view>
                    <view class="iconfont icon-arrow-down"/>
                  </view>
                </picker>
              </view>
              <view class="scene-box line-field">
                <view class="label">场景</view>
                <view class="content">
                  <picker
                      mode="selector"
                      :value="item.scene"
                      :range="sceneBaseList"
                      rangeKey="name"
                      @change="changeScene($event, item)">
                    <view class="picker-box">
                      <view v-if="item.scene !== null" class="picker-value">
                        {{ sceneBaseList[item.scene].name }}
                      </view>
                      <view v-else class="placeholder">
                        请选择场景
                      </view>
                      <view class="iconfont icon-arrow-down"/>
                    </view>
                  </picker>
                </view>
              </view>
            </view>
            <view v-if="formVerify.timeListError" class="error-tips">{{ formVerify.timeListErrorTips }}</view>
            <view class="time-item">
              <view class="line-field">
                <view class="label">
                  <text>其他时间</text>
                </view>
                <view class="content">
                  <picker
                      mode="selector"
                      :value="form.scene"
                      :range="sceneBaseList"
                      rangeKey="name"
                      @change="changeScene($event, form)">
                    <view class="picker-box">
                      <view v-if="form.scene !== null" class="picker-value">
                        {{ sceneBaseList[form.scene].name }}
                      </view>
                      <view v-else class="placeholder">
                        请选择场景
                      </view>
                      <view class="iconfont icon-arrow-down"/>
                    </view>
                  </picker>
                </view>
              </view>
            </view>
            <view v-if="formVerify.sceneError" class="error-tips">{{ formVerify.sceneErrorTips }}</view>
          </view>
        </view>
      </view>
    </view>
    <view v-show="enableEdit" class="page-bottom-btn" @click="saveSetting()">确定</view>
  </view>
</template>

<script>
import mixin from '@/mixins/index.js'
import { formatDate, getGUID } from '@/utils';
import { SCENE_TIME_TYPE, WEEKDAY } from '@/constant';

export default {
  mixins: [mixin],
  data() {
    return {
      SCENE_TIME_TYPE,
      enableEdit: false,
      typeList: [
        {
          name: '每天重复',
          value: SCENE_TIME_TYPE.DAILY,
        },
        {
          name: '每周重复',
          value: SCENE_TIME_TYPE.WEEKLY,
        },
        {
          name: '指定日期',
          value: SCENE_TIME_TYPE.DATE_AREA,
        },
      ],
      weekdayList: [
        {
          name: '周一',
          value: WEEKDAY.MON,
        },
        {
          name: '周二',
          value: WEEKDAY.TUE,
        },
        {
          name: '周三',
          value: WEEKDAY.WED,
        },
        {
          name: '周四',
          value: WEEKDAY.THU,
        },
        {
          name: '周五',
          value: WEEKDAY.FRI,
        },
        {
          name: '周六',
          value: WEEKDAY.SAT,
        },
        {
          name: '周日',
          value: WEEKDAY.SUN,
        },
      ],
      sceneBaseList: [],
      sceneMap: {},
      form: {
        id: null,
        name: '',
        type: SCENE_TIME_TYPE.DAILY,
        weekdays: [],
        dateArea: [],
        timeList: [],
        scene: null,
      },
      formVerify: {
        nameErrorTips: '请输入时控名称',
        nameError: false,
        timeListErrorTips: '请设置正确的时间段和场景',
        timeListError: false,
        weekdayErrorTips: '请设置每周重复的时间',
        weekdayError: false,
        dateAreaErrorTips: '请设置指定的日期',
        dateAreaError: false,
        sceneErrorTips: '请选择场景',
        sceneError: false,
      },
    }
  },
  mounted() {
    this.enableEdit = this.params.canEdit === 'true'
    this.getProjectScene()
    if (this.params.id) {
      uni.setNavigationBarTitle({
        title: this.enableEdit ? '编辑时控' : '查看时控'
      })
    } else {
      this.form.timeList = [this.generateTimeItem()]
    }
  },
  methods: {
    getProjectScene() {
      const self = this
      self.sceneBaseList = []
      uni.request({
        url: '/project_scene/list',
        data: {
          xm_id: self.params.projectId
        },
        success(result) {
          if (result.data.success && Array.isArray(result.data.data)) {
            const baseScene = [];
            result.data.data.forEach(item => {
              const sceneItem = {
                key: item.id,
                id: item.id,
                name: item.name || '',
                text: item.name || '',
                value: item.id,
                type: item.type,
                scene: item.scene,
                scene_type: item.scene_type,
                weekdays: item.weekdays,
                date_start: item.date_start,
                date_end: item.date_end,
              }
              if (item.scene_type === 0) {
                sceneItem.index = baseScene.length
                baseScene.push(sceneItem);
                self.sceneMap[sceneItem.id] = sceneItem
              }
              if (item.id === Number(self.params.id)) {
                self.initScene(sceneItem)
                self.getSceneTimeList()
              }
            })
            self.sceneBaseList = baseScene
          }
        }
      })
    },
    initScene(target) {
      this.form.id = target.id;
      this.form.name = target.name;
      this.form.type = target.scene_type;
      this.form.weekdays = this.getWeekdaysByStr(target.weekdays);
      this.form.scene = this.sceneMap[target.scene]?.index ?? null;
      this.form.dateArea = [formatDate(target.date_start, 'yyyy-MM-dd'), formatDate(target.date_end, 'yyyy-MM-dd')];
    },
    getWeekdaysByStr(weekdays) {
      if (weekdays.length !== 7) return [];
      const arr = [];
      weekdays.split('').forEach((item, index) => {
        if (item === '1') {
          arr.push(index);
        }
      });
      return arr;
    },
    generateTimeItem(target) {
      const item = {
        key: getGUID(),
        id: 0,
        startTime: '',
        endTime: '',
        scene: null,
        error: false,
      };
      if (target) {
        item.id = target.id
        item.startTime = target.time_start.substring(0, 5)
        item.endTime = target.time_end.substring(0, 5)
        item.scene = this.sceneMap[target.scene]?.index ?? null
      }
      return item
    },
    getSceneTimeList() {
      const self = this
      uni.request({
        url: '/project_scene_time/list',
        data: {
          project_scene_id: self.params.id,
        },
        success(result) {
          if (result.data.success && Array.isArray(result.data.data)) {
            const arr = [];
            result.data.data.forEach((item) => {
              arr.push(self.generateTimeItem(item));
            });
            self.form.timeList = arr.length ? arr : [self.generateTimeItem()];
          }
        }
      })
    },
    toggleWeekChecked(week) {
      if (this.form.weekdays.includes(week)) {
        this.form.weekdays = this.form.weekdays.filter((item) => item !== week);
      } else {
        this.form.weekdays.push(week)
      }
    },
    addSceneTime() {
      this.form.timeList.push(this.generateTimeItem());
    },
    changeTime(e, target, type) {
      target[`${type}Time`] = e.detail.value
    },
    changeScene(e, target) {
      target.scene = e.detail.value
    },
    removeSceneTime(target) {
      this.form.timeList = this.form.timeList.filter((item) => item.key !== target.key);
    },
    validateName() {
      this.form.name = this.form.name.trim();
      if (!this.form.name) {
        this.formVerify.nameError = true;
        return false;
      }
      return true;
    },
    validateTimeArea() {
      if (!this.form.timeList.length) {
        this.formVerify.timeListError = true;
        return false;
      }
      let isOK = true;
      this.form.timeList.forEach((item) => {
        item.error = !item.startTime || !item.endTime || item.scene === null;
        isOK = isOK && !item.error;
      });
      this.formVerify.timeListError = !isOK;
      return isOK;
    },
    validateScene() {
      if (!this.form.scene) {
        this.formVerify.sceneError = true;
        return false;
      }
      return true;
    },
    validateWeekday() {
      if (this.form.type === SCENE_TIME_TYPE.WEEKLY && !this.form.weekdays.length) {
        this.formVerify.weekdayError = true;
        return false;
      }
      return true;
    },
    validateDateArea() {
      if (this.form.type === SCENE_TIME_TYPE.DATE_AREA && (!this.form.dateArea[0] || !this.form.dateArea[1])) {
        this.formVerify.dateAreaError = true;
        return false;
      }
      return true;
    },
    resetValidator() {
      this.formVerify.nameError = false;
      this.formVerify.timeListError = false;
      this.formVerify.sceneError = false;
      this.formVerify.weekdayError = false;
      this.formVerify.dateAreaError = false;
      this.form.timeList.forEach((item) => {
        item.error = false;
      });
    },
    validate() {
      this.resetValidator();
      const namePass = this.validateName();
      const timeAreaPass = this.validateTimeArea();
      const scenePass = this.validateScene();
      const weekdayPass = this.validateWeekday();
      const dateAreaPass = this.validateDateArea();
      return namePass && timeAreaPass && scenePass && weekdayPass && dateAreaPass;
    },
    async saveSetting() {
      const self = this
      if (!self.validate()) {
        return;
      }
      const data = {
        xm_id: self.params.projectId,
        name: self.form.name,
        scene_type: self.form.type,
        scene: self.sceneBaseList[self.form.scene]?.id,
      }
      if (self.params.id) {
        data.id = self.params.id
      }
      if (self.form.type === SCENE_TIME_TYPE.WEEKLY) {
        data.weekdays = Array.from(self.weekdayList, (item) => (+self.form.weekdays.includes(item.value))).join('');
      }
      if (self.form.type === SCENE_TIME_TYPE.DATE_AREA) {
        const [start, end] = self.form.dateArea;
        data.date_start = formatDate(start, 'yyyyMMdd');
        data.date_end = formatDate(end, 'yyyyMMdd');
      }
      const timeList = [];
      self.form.timeList.forEach((item) => {
        timeList.push({
          id: item.id || 0,
          scene: self.sceneBaseList[item.scene].id,
          time_start: `${item.startTime}:00`,
          time_end: `${item.endTime}:00`
        });
      });
      const sceneId = await self.saveScene(data);
      const timeListData = {
        project_scene_id: data.id || sceneId,
        data: JSON.stringify(timeList),
      };
      await this.saveTimeList(timeListData);
      uni.showToast({
        icon: 'none',
        title: '保存成功'
      })
      self.goBack()
    },
    saveScene(data) {
      const self = this
      return new Promise((resolve, reject) => {
        const url = self.params.id ? '/project_scene/modify' : '/project_scene/add';
        uni.request({
          url,
          data,
          success(result) {
            if (result.data.success && result.data.data) {
              resolve(result.data.data.insertId);
            } else {
              reject();
            }
          },
          fail() {
            reject();
          }
        })
      });
    },
    saveTimeList(data) {
      return new Promise((resolve, reject) => {
        uni.request({
          url: '/project_scene_time/save',
          method: 'POST',
          data,
          success(result) {
            if (result.data.success) {
              resolve();
            } else {
              reject();
            }
          },
          fail() {
            reject();
          }
        })
      });
    },
    goBack() {
      uni.navigateBack();
    }
  }
}
</script>

<style scoped lang="scss">
.add-time-scene {
  position: relative;
  min-height: 100vh;
  padding: 30rpx 30rpx 130rpx;
  font-size: 28rpx;
}
.section-box {
  background-color: $white;
  border-radius: 10rpx;
  padding: 30rpx;
  margin-bottom: 20rpx;
}
.section-title {
  @include section-title;
  margin-bottom: 30rpx;
}
.add-time {
  color: $primary;
  white-space: nowrap;
  .iconfont {
    margin-right: 10rpx;
  }
}
.error-tips {
  color: $danger;
  margin-top: 10rpx;
}
.type-box {
  margin-top: 20rpx;
  display: flex;
  justify-content: space-between;
  align-items: center;
  .like-radio {
    margin-right: 20rpx;
  }
}
.item-line {
  margin-top: 30rpx;
  &:first-child {
    margin-top: 0;
  }
}
.line-field {
  display: flex;
  align-items: center;
  justify-content: space-between;
  .label {
    font-size: $font-size-3;
    vertical-align: baseline;
    .info {
      font-size: $font-size-0;
      color: $text-secondary;
    }
  }
  .content {
    text-align: right;
    .picker-box {
      justify-content: flex-end;
    }
  }
}
.item-operate {
  margin-top: 40rpx;
  .operate-label {
    font-size: $font-size-3;
    font-weight: bold;
  }
  .line-desc {
    font-size: $font-size-0;
    color: $text-secondary;
  }
}
.operate {
  position: relative;
  text-align: right;
  input {
    font-size: 28rpx;
  }
}
.week-box {
  display: flex;
  .week-item {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 1;
    padding: 12rpx 0;
    border: 2rpx solid $border-base;
    border-right: 0;
    font-size: 28rpx;
    &:first-child {
      border-top-left-radius: 10rpx;
      border-bottom-left-radius: 10rpx;
      &.active {
        border-left-color: $primary;
      }
    }
    &:last-child {
      border-right: 2rpx solid $border-base;
      border-top-right-radius: 10rpx;
      border-bottom-right-radius: 10rpx;
    }
    &.active {
      background-color: $primary;
      border-color: $primary;
      border-left-color: $border-base;
      color: #fff;
    }
  }
}
.time-item {
  padding: 30rpx;
  background-color: $background-base;
  position: relative;
  margin-top: 30rpx;
  :first-child {
    margin-top: 0;
  }
  .delete-item {
    position: absolute;
    font-size: 40rpx;
    color: $danger;
    top: -20rpx;
    right: -20rpx;
  }
}
.icon-arrow-down {
  margin-left: 8rpx;
  color: $text-secondary;
}
.placeholder {
  color: $text-secondary;
}
.picker-box {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 260rpx;
}
.time-box {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.scene-box {
  margin-top: 20rpx;
  border-top: 2rpx solid $border-base;
  padding-top: 20rpx;
}
::v-deep {
  .uni-calendar-item--multiple .uni-calendar-item--before-checked,
  .uni-calendar-item--multiple .uni-calendar-item--after-checked {
    background-color: rgba($primary, 0.7) !important;
  }
  .uni-calendar-item__weeks-box .uni-calendar-item--checked {
    background-color: $primary !important;
  }
  .uni-datetime-picker--btn {
    background-color: $primary !important;
  }
}
</style>
